#!/bin/sh

usage() {
	cat <<EOF>&2
Usage: ${0##*/}

Sync home folder.
Data is indexed to \$PERSONAL/index.

The '~/.gnupg' folder can be backup up to a LUKS encrypted device.

Options:

  -d PATH:   where the data is looked up for indexing.
  -g DEVICE: Device where to sync ~/.gnupg.
  -p:        Push upstream.

EOF
	exit
}

OPT_UPDATE=false
OPT_DEVICE=""
OPT_DATAROOT=$(findmnt -n --fstab --output TARGET | grep ^/media/)
[ -z "$OPT_DATAROOT" ] && OPT_DATAROOT=$(findmnt -n --list --output TARGET | grep ^/media/)
while getopts ":hd:g:p" opt; do
	case $opt in
	h)
		usage
		exit ;;
	d)
		OPT_DATAROOT="$OPTARG" ;;
	p)
		OPT_UPDATE=true ;;
	g)
		OPT_DEVICE="$OPTARG" ;;
	\?)
		usage
		exit 1 ;;
	esac
done

shift $(($OPTIND - 1))

[ -z "$PERSONAL" ] && echo >&2 'Set $PERSONAL to project directory.' && exit 1
[ -z "$XDG_CONFIG_HOME" ] && XDG_CONFIG_HOME="$HOME/.config"
[ -z "$XDG_DATA_HOME" ] && XDG_DATA_HOME="$HOME/.local/share"

RED='\033[0;31m\033[1m'
GREEN='\033[0;32m\033[1m'
YELLOW='\033[0;33m\033[1m'
BOLD='\033[0m\033[1m'
NORMAL='\033[0m'

section() {
	echo -e "$GREEN==> $@$NORMAL"
}
message() {
	echo -e "$YELLOW:: $@$NORMAL"
}

if [ -n "$OPT_DATAROOT" ]; then
	section Data index
	for i in "$OPT_DATAROOT"/*; do
		mkdir -p "$PERSONAL"/index/
		case "$i" in
		*/locate.db|*/lost+found|*/Sync*)
			continue ;;
		*/public)
			for j in "$i"/*; do
				case "$j" in
				*/games|*/videos)
					for k in "$j"/*; do
						folder=$(basename $(dirname "$k"))
						mkdir -p "$PERSONAL"/index/"$folder"
						dataindex "$k" > "$PERSONAL"/index/"$folder"/"$(basename "$k")".index
						unset folder
					done ;;
				*)
					dataindex "$j" > "$PERSONAL"/index/"$(basename "$j")".index ;;
				esac
			done
			continue ;;
		*/private)
			for j in "$i"/*; do
				mkdir -p "$PERSONAL"/index/private
				[ -e "$j"/.encfs*.xml ] && continue
				dataindex "$j" | gpg --encrypt --recipient mail@ambrevar.xyz \
														 --output - > "$PERSONAL"/index/private/"$(basename "$j")".index.gpg
			done
			continue ;;
		esac
	done
fi

if [ -n "$OPT_DEVICE" ]; then
	section "GnuPG"
	sudo cryptsetup open "$OPT_DEVICE" gpg_backup
	MOUNT_POINT=/mnt
  # MOUNT_POINT=/media/ambrevar/gpg_backup
	sudo mount -o compress=zstd /dev/mapper/gpg_backup "$MOUNT_POINT"
	gpg --import "$MOUNT_POINT"/public/.gnupg/pubring.gpg
	sudo btrfs subvolume snapshot -r "$MOUNT_POINT"/public "$MOUNT_POINT"/.snapshots/public.$(date +%F_%R:%S) && \
		rm -rfv "$MOUNT_POINT"/public/.gnupg && \
		cp -av ~/.gnupg "$MOUNT_POINT"/public/
	sudo umount "$MOUNT_POINT"
	sudo cryptsetup close gpg_backup
	unset MOUNT_POINT
fi

if [ -e ~/.cache/mail/.notmuch ]; then
	section "Notmuch tags"
	notmuch restore --accumulate --input="$PERSONAL"/mail/notmuch.dump
	emacs --quick --batch --load=$HOME/.emacs.d/lisp/init-notmuch-sync.el \
				-f notmuch-dump-important-tags
fi

for i in "$PERSONAL"/games/stowed-saves/*; do
	section "Stowing '$i'"
	stow -t ~ -d "$(dirname "$i")" "$(basename "$i")"
done

project_status() {
	local path=$1
	local title=$2
	local body=$3

	[ -z "$body" ] && return

	if $CHANGED; then
		section "$path"
		CHANGED=false
	fi
	message "$title"
	echo "$body"
}

for i in ~/.password-store ~/common-lisp/* ~/projects/* ~/.local/share/emacs/site-lisp/* "$@"; do
	[ ! -d "$i/.git" ] && continue
	CHANGED=true
	push=$(git -C "$i" rev-parse --abbrev-ref --symbolic-full-name @{push} 2>&1)
	if [ $? -eq 0 ]; then
		unmerged=$(git -C "$i" log --oneline  "$push"..)
		project_status "$i" "Unpushed commits" "$unmerged"
	else
		project_status "$i" "Unpushed commits" "No 'push' remote"
	fi
	project_status "$i" "Unstaged files" "$(git -C "$i" diff --name-only)"
	project_status "$i" "Staged files" "$(git -C "$i" diff --name-only --cached)"
	if $OPT_UPDATE && [ -n "$unmerged" ]; then
		message "Pushing"
		git -C "$i" push
	fi
done
